Алексей Плуталов, Злые Марсиане
Modular CSS preprocessing with rework
@tjholowaychuk, Февраль 2013
Например, stylelint:
#bad-selector {background: red;}
Unexpected id selector (selector-no-id) [stylelint]
$background-color: red;body {background: $background-color;}
| Плагин | Строк кода |
|---|---|
| postcss-simple-vars | 92 |
| postcss-mixins | 186 |
| postcss-nested | 73 |
import postcss from 'postcss';postcss([ plugin1, plugin2 ]).process(css).then( result => console.log(result.css) );
gulp.task('css', () => {return gulp.src('./components/**/*.css').pipe(postcss([autoprefixer({ browsers: [ 'last 2 versions' ] }),cssnano]).pipe(gulp.dest('./dest'));});
export default {module: {loaders: [ {test: /\.css$/,loader: 'style-loader!css-loader!postcss-loader'} ]},postcss () {return [ autoprefixer({ browsers: [ 'last 2 versions' ] }),cssnano ];}}
@use postcss-circle;.circle {circle: 100px red;}
.pipe(less()).pipe(postcss([require('autoprefixer-core'),require('cssnext'),require('cssnano')])
.pipe(postcss([require('precss'),require('autoprefixer-core'),require('cssnano')])
$small-width: 960px;$large-width: calc($small-width + 1px);@custom-media --small (max-width: $small-width);@custom-media --large (min-width: $large-width);.cards {@media (--small) {width: auto;}&&_narrow {@media (--large) {width: $small-width;}}}
@media (max-width: 960px) {.cards {width: auto;}}@media (min-width: 961px) {.cards.cards_narrow {width: 960px;}}
@import 'config/icons.css';.icon {&_small { size: $icon-s-size; }&_medium { size: $icon-m-size; }&_large { size: $icon-l-size; }}
import sizes from 'config/icons';export default simpleVars({'icon-s-size': toPx(sizes.small),'icon-m-size': toPx(sizes.medium),'icon-l-size': toPx(sizes.large)});
import step from 'config/step';postcss.plugin('postcss-default-step', () => {/* реализация плагина */});
import screen from 'config/screen';const DesktopOnlyMixin = {/* реализация миксина для React */};
size: $height $width {height: $height;width: $width;}size: $size {height: $size;width: $size;}
.rectangle {size: 50px 100px;}.square {size: 50px;}
@define-mixin icon $name {.icon.icon_$(name) {background: url(icons/$(name).svg);@mixin-content;}}@mixin icon twitter {width: 16px;height: 16px;}
.icon.icon_twitter {background: url(icons/twitter.svg);width: 16px;height: 16px;}
require('postcss-mixins')({mixins: {clearfix () {return {'&::after': {content: '""';display: 'table';clear: 'both';}};}}});
.column {@mixin clearfix;}.column::after {content: "";display: table;clear: both;}
require('postcss-mixins')({mixins: {mixinName (mixinAST, ...mixinArgs) {/* реализация миксина */}}});
Кастомные свойства → Миксины → Плагины
.example {size: 10px 20px; /* Кастомное свойство */@mixin icon twitter; /* Миксин */clear: fix; /* Плагин */}
@component button {font-size: 12px;@modifier large {font-size: 16px;}@descendent icon {margin-right: 6px;}}
.button {font-size: 12px;}.button_large {font-size: 16px;}.button__icon {margin-right: 6px;}
/* @define Button */.Button { }.Button--large { }.Button-icon { }.Button.is-disabled { }
.className {color: green;}
import styles from './style.css';return `<div class="${ styles.className }">`;
:local .Button {font-size: 12px;&:focus {box-shadow: 0 0 1px 5px #999;}/* className--propsKey-propsValue */&--kind-default { }&--kind-success { }&--kind-warning { }}
import css from './button.css';@EasyStyle(css)class Button extends React.Component {static defaultProps = {kind: 'default'}render () {return (<button>{ this.props.label }</button>);}}
:root {--mainFontSize: 12px;}@custom-selector :--button button, .button:--button {font-size: var(--mainFontSize);}
div {display: flex;min-height: 50vh;}
div {display: flex;height: 50vh;}
@import 'normalize.css/normalize';@import 'mobile/index.css' (max-width: 25em);
/* содержимое './node_modules/normalize.css/normalize.css' */@media (max-width: 25em) {/* содержимое mobile/index.css */}
.icon { background: url(small-image.png); }.backing { background: url(large-image.png); }
.icon { background: url(data:image/png;base64,...); }.backing { background: url(/assets/large-image.png); }
body {font-family: 'Roboto';}
@font-face {/* определение Roboto */}body {font-family: 'Roboto';}
.icon { background-image: url(images/icon.png); }
.icon { background-image: url(images/icon.png); }.webp .icon { background-image: url(images/icon.webp); }
/postcss|- /config|- /mixins|- index.js экспорт сконфигурированного списка плагинов|- media.js экспорт кастомных медиавыражений|- mixins.js экспорт миксин|- utils.js вспомогательные функции|- variables.js экспорт переменных
/test|- /fixtures| |- postcss|- /postcss| |- /config| |- /mixins| |- index.js тесты экспорта плагинов| |- integration.js тесты интеграции между плагинами